import {
  CryptoManager
} from '../crypto_manager/CryptoManager';
import {
  ExtVsMimeDict
} from './MimeExtMap';
import {
  Context
} from '@ohos.arkui.UIContext';
import {
  util
} from '@kit.ArkTS';

/**
 * FilePathGenerator
 * 只负责生成App需要使用文件的路径.
 */


export class FilePathGenerator {
  static context: Context;
  // 应用沙盒中的文件目录
  static rootDir?: string
  static mailsDir?: string
  static buffDir?: string
  static cacheDir?: string
  static dbDir?: string
  static logDir?: string

  /**
   *
   * @param rootDir
   * @param cache 自定义缓存目录
   */
  static initClass(context: Context, rootDir: string, cache?: string) {
    this.context = context;
    FilePathGenerator.rootDir = rootDir;
    FilePathGenerator.cacheDir = cache || `${FilePathGenerator.rootDir}/cache`
    FilePathGenerator.mailsDir = `${FilePathGenerator.rootDir}/mails`
    FilePathGenerator.buffDir = `${FilePathGenerator.rootDir}/buffers`
    FilePathGenerator.dbDir = `${FilePathGenerator.rootDir}/dbs`
    FilePathGenerator.logDir = `${FilePathGenerator.rootDir}/logs`
  }


  /**
   * 获取一个唯一的临时文件路径
   */
  static getTmpCachePath() {
    return `${this.context.cacheDir}/${util.generateRandomUUID().toString()}.cache`
  }


  /**
   * mailKey由mid和folderFullName组成的字符串hash得到.
   * 不同文件夹的mail可能会有相同的mid;
   * @param mid 邮件的mid
   * @param folderFullName 邮件的文件夹
   */
  static async getDirPathForAccountMail(account: string, folderFullName: string, mid: string): Promise<string> {
    let accountKey: string = await CryptoManager.md5String(account);
    let mailKey: string = await CryptoManager.md5String(mid + folderFullName)
    let dirPath = `${FilePathGenerator.mailsDir!}/${accountKey}/${mailKey}`
    return dirPath;
  }

  static async getDirPathForAccount(account: string) {
    let accountKey: string = await CryptoManager.md5String(account);
    let dirPath = `${FilePathGenerator.mailsDir!}/${accountKey}`
    return dirPath;
  }

  static getFileTitleFromName(name: string) {
    let index = name.indexOf(".");
    return index == -1 ? name : name.substring(0, index);
  }

  /**
   * 先从filename取后缀,没有的话根据fileType取,都没有,返回unknown作为后缀名.
   * @param name
   * @param fileType
   * @returns
   */
  static getFileExtFromNameAndType(name: string, fileType: string) {
    let index = name.indexOf(".");
    if (index != -1) {
      return name.substring(index + 1);
    } else {
      let ext = Object.entries(ExtVsMimeDict).find(item => item[1].endsWith(fileType));
      if (ext) {
        return ext[0];
      } else {
        return "unknown";
      }
    }
  }

  static async getDirPathForImportedMail(url: string): Promise<string> {
    let mailKey: string = await CryptoManager.md5String(url)
    return `${FilePathGenerator.mailsDir!}/imported/${mailKey}`
  }

  static async getEmlPathForAccountMail(account: string, folderFullName: string, mid: string): Promise<string> {
    let mailDir = await this.getDirPathForAccountMail(account, folderFullName, mid);
    return `${mailDir}/index.eml`
  }

  static async getHtmlPathForAccountMail(account: string, folderFullName: string, mid: string): Promise<string> {
    let mailDir = await this.getDirPathForAccountMail(account, folderFullName, mid);
    return `${mailDir}/index.html`
  }

  static async getTextPathForAccountMail(account: string, folderFullName: string, mid: string): Promise<string> {
    let mailDir = await this.getDirPathForAccountMail(account, folderFullName, mid);
    return `${mailDir}/index.txt`
  }

  static async getEmlPathForImportedMail(url: string): Promise<string> {
    let mailDir = await this.getDirPathForImportedMail(url);
    return `${mailDir}/index.eml`
  }

  static async getHtmlPathForImportedMail(url: string): Promise<string> {
    let mailDir = await this.getDirPathForImportedMail(url);
    return `${mailDir}/index.html`
  }

  static async getTextPathForImportedMail(url: string): Promise<string> {
    let mailDir = await this.getDirPathForImportedMail(url);
    return `${mailDir}/index.txt`
  }

  static getFileNameWithIndex(fileTitle: string, fileExtension: string, index: number): string {
    return `${fileTitle}_${index}.${fileExtension}`
  }

  static async getAttachmentPathForAccountMail(account: string, folderFullName: string, mid: string, isInline: boolean, fileTile: string, fileExtension: string, index: number): Promise<string> {
    let mailDir = await FilePathGenerator.getDirPathForAccountMail(account, folderFullName, mid);
    let attachPath = `${mailDir}/${isInline ? "inline" : "extern"}/${FilePathGenerator.getFileNameWithIndex(fileTile, fileExtension, index)}`
    return attachPath
  }

  static async getAttachmentPathForImportedMail(url: string, isInline: boolean, fileTile: string, fileExtension: string, index: number): Promise<string> {
    let mailDir = await FilePathGenerator.getDirPathForImportedMail(url);
    let attachPath = `${mailDir}/${isInline ? "inline" : "extern"}/${FilePathGenerator.getFileNameWithIndex(fileTile, fileExtension, index)}`
    return attachPath;
  }

  static getFileContentType(fileName: string): string | undefined {
    let ext = fileName.split(".").pop();
    return ext ? ExtVsMimeDict[ext] : undefined;
  }

  static async getAttachmentDirPath(account: string, folderFullName: string, mid: string, isInline: boolean) {
    let mailDir = await FilePathGenerator.getDirPathForAccountMail(account, folderFullName, mid);
    return `${mailDir}/${isInline ? "inline" : "extern"}`
  }
}

